package main

import "fmt"

// 向intChan放入1-8000个数
func putNum(intChan chan int) {

	for i := 1; i <= 8000; i++ {
		intChan <- i
	}

	// 关闭intChan
	close(intChan)

}

func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) {
	// 使用for循环
	var flag bool
	for {
		num, ok := <- intChan
		if !ok {
			break
		}
		flag = true
		// 判断num是不是素数
		for i := 2; i < num; i++ {
			if num % i == 0 {
				flag = false
				break
			}
		}
		if flag {
			// 将这个数放入到primeChan
			primeChan <- num
		}
	}
	fmt.Println("有一个primeNum协程因为取不到数据，退出了")
	// 向exitChan写入true
	exitChan <- true
}


func main() {

	intChan := make(chan int, 1000)
	primeChan := make(chan int, 2000) // 放入结果
	exitChan := make(chan bool, 4)

	// 开启一个协程，向intChan放入1-8000个数
	go putNum(intChan)
	// 开启4个协程，从intChan取出数据，并判断是否为素数
	// 如果是就放入primeChan
	for i := 0; i < 4; i++ {
		go primeNum(intChan, primeChan, exitChan)
	}

	// 主线程进行阻塞处理
	go func() {
		for i := 0; i < 4; i++ {
			<-exitChan
		}

		// 当我们从exitChan取出了4个结果，就可以放心的关闭primeNum
		close(primeChan)
	}()

	// 遍历primeNum
	for {
		res, ok := <- primeChan
		if !ok {
			break
		}
		fmt.Printf("素数=%d\n", res)
	}

	fmt.Println("主线程退出")

}